/* WOSS - World Ocean Simulation System -
 * 
 * Copyright (C) 2009 Federico Guerra
 * and regents of the SIGNET lab, University of Padova
 *
 * Author: Federico Guerra - federico@guerra-tlc.com
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation;
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */ 

/*
 * This software has been developed by Federico Guerra and SIGNET lab,
 * University of Padova, in collaboration with the NATO Centre for 
 * Maritime Research and Experimentation (http://www.cmre.nato.int ; 
 * E-mail: pao@cmre.nato.int), whose support is gratefully acknowledged.
 */


/**
 * @file   ac-toolbox-arr-bin-reader.h
 * @author Federico Guerra
 * 
 * \brief Provides the interface for woss::ArrBinResReader class
 *
 * Provides the interface for the woss::ArrBinResReader class
 */


#ifndef AC_TOOLBOX_ARR_BIN_READER_DEFINITIONS_H
#define AC_TOOLBOX_ARR_BIN_READER_DEFINITIONS_H


#include "ac-toolbox-arr-asc-reader.h"


namespace woss {
  
    
  /**
  * \brief Class for reading and manipulating results provided by any acoustic toolbox binary ARR file
  *
  * Class ArrAscResReader stores TimeArr provided by any acoustic toolbox binary ARR file in a ArrStruct. It also offers
  * TimeArr manipulation and Pressure conversion methods.
  */
  class ArrBinResReader : public ResReader {


    public:


    /**
    * ArrBinResReader default constructor
    */
    ArrBinResReader();

    /**
    * ArrBinResReader constructor
    * @param woss const pointer to a const Woss object
    */
    ArrBinResReader( const Woss* const woss );

    
    virtual ~ArrBinResReader();


    /**
    * Initializes the ArrBinResReader object, reads ARR file, and stores read TimeArr values
    * @return <i>true</i> if method was successful, <i>false</i> otherwise
    **/
    virtual bool initialize();


    /**
    * Gets the average Pressure value in given rx range-depth box. Returned Pressure is the coherent sum of the computed 
    * average TimeArr
    * @param frequency frequency [hZ]
    * @param tx_depth transmitter depth [m]
    * @param start_rx_depth start receiver depth [m]
    * @param start_rx_range start receiver range [m]
    * @param end_rx_depth end receiver depth [m]
    * @param end_rx_range end receiver range [m]
    * @return a valid Pressure value; a not valid Pressure if arr_file hasn't been read yet
    **/  
    virtual Pressure* readAvgPressure( double frequency, double tx_depth, double start_rx_depth, double start_rx_range, double end_rx_depth, double end_rx_range );

    /**
    * Gets a Pressure value for given range, depths. Returned Pressure is the coherent sum of the computed 
    * TimeArr
    * @param frequency frequency [hZ]
    * @param tx_depth transmitter depth [m]
    * @param rx_depth receiver depth [m]
    * @param rx_range receiver range [m]
    * @return a valid Pressure value; a not valid Pressure if arr_file hasn't been read yet
    **/
    virtual Pressure* readPressure(double frequency, double tx_depth, double rx_depth, double rx_range ) const; 
    

    /**
    * Gets a TimeArr value for given range, depths
    * @param frequency frequency [hZ]
    * @param tx_depth transmitter depth [m]
    * @param rx_depth receiver depth [m]
    * @param rx_range receiver range [m]
    * @return a valid TimeArr value; a not valid TimeArr if arr_file hasn't been read yet
    **/
    virtual TimeArr* readTimeArr(double frequency, double tx_depth, double rx_depth, double rx_range ) const;
    

    protected:
    
      
    /**
    * Boolean associated to the reading of ARR file header
    */
    bool arr_bin_header_collected;
    
    /**
    * Boolean associated to the reading of ARR file data
    */
    bool arr_bin_file_collected;


    /**
    * Input file stream 
    */
    ::std::ifstream file_reader;

    /**
    * Total lines to skip if ARR file header has already been read
    */
    ::std::streampos skip_header;


    /**
    * Struct that holds TimeArr data read from ARR file
    */
    ArrData arr_file;

    double last_tx_depth;

    double last_start_rx_depth;

    double last_start_rx_range;

    double last_end_rx_depth;

    double last_end_rx_range;

    ::std::complex<double> last_ret_value;


    /**
    * Gets the TimeArr value from ArrData TimeArr array associated to given parameters
    * @param frequency frequency [hZ]
    * @param tx_depth transmitter depth [m]
    * @param rx_depth start receiver depth [m]
    * @param rx_range start receiver range [m]
    * @return a valid TimeArr value; a not valid TimeArr if arr_file hasn't been read yet
    **/  
    TimeArr* accessMap(double frequency, double tx_depth, double rx_depth, double rx_range) const {
      return( arr_file.arr_values + arr_file.getTimeArrIndex( tx_depth, rx_depth, rx_range ) );
    }

    /**
    * Gets the average Pressure value in given rx range-depth box converted from ArrStruct TimeArr array
    * @param frequency frequency [hZ]
    * @param tx_depth transmitter depth [m]
    * @param start_rx_depth start receiver depth [m]
    * @param start_rx_range start receiver range [m]
    * @param end_rx_depth end receiver depth [m]
    * @param end_rx_range end receiver range [m]
    * @return a valid Pressure value; a not valid Pressure if arr_file hasn't been read yet
    **/  
    ::std::complex<double> readMapAvgPressure( double frequency, double tx_depth, double start_rx_depth, double start_rx_range, double end_rx_depth, double end_rx_range );


    /**
    * Process the ARR file header
    * @return <i>true</i> if method was successful, <i>false</i> otherwise
    **/
    bool getArrBinHeader();

    /**
    * Process the ARR file data
    * @return <i>true</i> if method was successful, <i>false</i> otherwise
    **/
    bool getArrBinFile();
    
    
  };

  
}


#endif /* AC_TOOLBOX_ARR_BIN_READER_DEFINITIONS_H */ 





